﻿var asos = asos || {};
asos.dataaccess = asos.dataaccess || {};
asos.dataaccess.cookies = (function() {
    var cookieArrayDelimiter = '|';
    var cookieLifetime = 365;
    var cookieApi = {
        setCookieLifetime: function(expiryDays) {
            cookieLifetime = expiryDays;
        },
        clear: function(name) {
            var expiryDate = new Date();
            expiryDate.setFullYear(1900, 1, 1);
            document.cookie = name + '=; expires=' + expiryDate.toUTCString() + '; path=/';
        },
        setString: function(name, value) {
            var expiryDate = new Date();
            expiryDate.setDate(expiryDate.getDate() + cookieLifetime);
            document.cookie = name + '=' + escape(value) + '; expires=' + expiryDate.toUTCString() + '; path=/';
        },
        getString: function(name) {
            if (document.cookie.length < 1) { // no cookies at all
                return '';
            }
            var cookieStartPosition = document.cookie.indexOf(name + "=");
            if (cookieStartPosition === -1) { // our cookie isn't there
                return '';
            }

            cookieStartPosition = cookieStartPosition + name.length + 1;
            var cookieEndPosition = document.cookie.indexOf(";", cookieStartPosition);
            if (cookieEndPosition === -1) {
                cookieEndPosition = document.cookie.length;
            }
            return unescape(document.cookie.substring(cookieStartPosition, cookieEndPosition));
        },
        setArray: function(name, value) {
            var textRepresentation = '';
            for (var i = 0; i < value.length; i++) {
                if (i !== 0) {
                    textRepresentation += cookieArrayDelimiter;
                }
                textRepresentation += value[i].replace(cookieArrayDelimiter, '');
            }
            cookieApi.setString(name, textRepresentation, cookieLifetime);
        },
        getArray: function(name) {
            var textRepresentation = cookieApi.getString(name);
            if (!textRepresentation || textRepresentation === '') {
                return [];
            }
            return textRepresentation.split(cookieArrayDelimiter);
        }
    };
    return cookieApi;
} ());
asos.model = asos.model || {};
asos.model.base = (function() {
    var isArray = function(o) {
        return Object.prototype.toString.call(o) === '[object Array]';
    };
    var inheritNewModel = function() {
        function F() { }
        F.prototype = this;
        return new F();
    };
    return {
        modelname: "base",
        dataAccess: asos.dataaccess.cookies,
        save: function(obj) {
            for (property in this) {
                if (this.hasOwnProperty(property) && property !== 'modelname') {
                    if (isArray(this[property])) {
                        this.dataAccess.setArray(this.modelname + '.' + property, obj[property]);
                    } else {
                        this.dataAccess.setString(this.modelname + '.' + property, obj[property]);
                    }
                }
            }
        },
        load: function() {
            var obj = inheritNewModel();
            for (property in this) {
                if (this.hasOwnProperty(property) && property !== 'modelname') {
                    if (isArray(this[property])) {
                        obj[property] = this.dataAccess.getArray(this.modelname + '.' + property);
                    } else {
                        obj[property] = this.dataAccess.getString(this.modelname + '.' + property);
                    }
                }
            }
            return obj;
        },
        inheritNewModel: inheritNewModel
    };
} ());

asos.model.customer = asos.model.base.inheritNewModel();
asos.model.customer.modelname = 'customer';
asos.model.customer.recentSearches = [];

// ------ Above and below this line combined into one file until more places need to use cookie storage

$(window).load(function() {
    var constant = {
        keyCodes: {
            upArrow: 38,
            downArrow: 40,
            enterButton: 13,
            tabKey: 9
        },
        mouseButtons: {
            left: 1,
            middle: 2,
            right: 3
        },
        isSearchSuggestEnabled: $("div.search input.IsSearchSuggestEnabled:first").val(),
        isRecentSearchesEnabled: $("div.search input.IsRecentSearchesEnabled:first").val(),
        searchSuggestJSONPService: $("div.search input.SearchSuggestJSONPService:first").val(),
        searchMaxResults: parseInt($("div.search input.SearchMaxResults:first").val(), 10),
        minimumInputCharactersBeforeSuggestions: 2,
        trimPathTemplateFile: "/templates/client/asos.web.searchsuggest.item.txt",
        recentSearchesToStore: 5,
        recentSearchesNewValue: $('input#RecentSearchesNewValue').val()
    };

    var trimPathTemplateObject = null;
    var currentSearchBox = null;
    var searchBoxDisplayedText = function() { return currentSearchBox.children('input.search-box').val() || ''; };
    var searchBoxLastTypedText = function() { return jQuery.data(currentSearchBox[0], 'lastTypedSearchTerm') || ''; };
    var openDropDownBoxType = function() { return jQuery.data(currentSearchBox[0], 'openDropDownBoxType') || ''; };
    var webTrendsTracking = {
        searchSuggestUsed: false,
        recentSearchesUsed: false
    };

    var init = function() {
        initSearchBox();
        if (constant.isSearchSuggestEnabled === "true" || constant.isRecentSearchesEnabled === "true") {
            initDropDownArea();
            if (constant.isSearchSuggestEnabled === "true") {
                initSearchSuggest();
            }
            if (constant.isRecentSearchesEnabled === "true") {
                initRecentSearches();
            }
        }
    };

    var initSearchBox = function() {
        $("div.search *").mousedown(function() {
            currentSearchBox = $(this).parents('div.search');
        });

        $("div.search input.search-box").keydown(function() {
            currentSearchBox = $(this).parents('div.search');
        });

        $("div.search label").click(function() {
            currentSearchBox.find("input.search-box").focus();
        });

        $("div.search a.clear-search").click(function() {
            currentSearchBox.find('a.clear-search').hide();
            if (searchBoxDisplayedText() !== "") {
                currentSearchBox.find('input.search-box').val('');
                currentSearchBox.find('input.search-box').focus();
            }
            return false;
        });

        $("div.search").bind('mouseover', function() {
            if ($(this).find('input.search-box').val() !== "") {
                $(this).find('a.clear-search').css('visibility', 'visible');
            }
        });

        $("div.search").bind('mouseout', function() {
            $(this).find('a.clear-search').css('visibility', 'hidden');
        });

        $("div.search input.search-box").focus(function() {
            currentSearchBox.find('label').fadeOut();

            // Function to add grey border to search box on focus
            currentSearchBox.find('input.search-box').addClass('add-border');
            currentSearchBox.find("a.go").addClass('add-border');
        });

        $("html").mouseup(function(event) {
            if (!currentSearchBox) {
                return;
            }
            var parentSearchBox = $(event.target).parents("div.search");
            $("div.search").each(function(i, o) {
                var searchBox = $(o);
                if (searchBox[0] !== currentSearchBox[0] || parentSearchBox[0] !== currentSearchBox[0]) {
                    closeSuggestionsBox(searchBox);
                    if (searchBox.find('input.search-box').val() === "") {
                        searchBox.find('label').fadeIn();

                        // Function to remove grey border to search box on focus
                        searchBox.find('input.search-box').removeClass('add-border');
                        searchBox.find('a.go').removeClass('add-border');
                    }
                }
            });
        });

        $("div.search input.search-box").keypress(function(event) {
            currentSearchBox.find('a.clear-search').hide();

            currentSearchBox.find('label').fadeOut();

            // Function to add grey border to search box on focus
            currentSearchBox.find('input.search-box').addClass('add-border');
            currentSearchBox.find("a.go").addClass('add-border');

            if (event.keyCode === constant.keyCodes.tabKey) {
                currentSearchBox.find("a.go").focus();
                return false;
            }
        });

        $("div.search a.go").click(function() {
            if (searchBoxDisplayedText() === "") {
                currentSearchBox.find("input.search-box").focus();
            } else {
                performSearch();
            }
            return false;
        });

        $("div.search a.go,input.search-box").keyup(function(event) {
            if (event.keyCode === constant.keyCodes.enterButton) {
                performSearch();
            }
        });

        $("div.search input.search-box").keypress(function(event) { // IE bug fix to stop 'ding' sound enter
            if (event.keyCode === constant.keyCodes.enterButton) { return false; }
        });

        var performSearch = function() {
            var searchTerm = searchBoxDisplayedText();
            if (searchTerm === "") {
                return;
            }

            var searchUrl = "/search/pgeSearch.aspx?hrd=1&q=" + urlEncodeForQueryString(searchTerm);
            if (webTrendsTracking.searchSuggestUsed) {
                searchUrl = searchUrl + "&SearchSuggestUsed=true";
            } else if (webTrendsTracking.recentSearchesUsed) {
                searchUrl = searchUrl + "&RecentSearchesUsed=true";
            }
            document.location = searchUrl;
            return true;
        };

        var urlEncodeForPath = function(str) {
            return urlEncode(str.replace(/[^a-zA-Z 0-9]+/g, '-'), '-');
        };

        var urlEncodeForQueryString = function(str) {
            return urlEncode(str, '+');
        };

        var urlEncode = function(str, spaceSeperator) {
            return encodeURIComponent(str).replace(/\+/g, '%2B').replace(/%20/g, spaceSeperator).replace(/\*/g, '%2A').replace(/\//g, '%2F').replace(/@/g, '%40');
        };

        $('div.search').each(function(i, o) {
            currentSearchBox = $(o);
            if (searchBoxDisplayedText().length !== 0) {
                currentSearchBox.find('a.clear-search').css('visibility', 'hidden');
                currentSearchBox.find('a.clear-search').show();
            }
            currentSearchBox.find('input.search-box').val(currentSearchBox.find('input.PageLoadedSearchTerm').val() || '');
            currentSearchBox = null;
        });
    };

    var initDropDownArea = function() {
        var currentSelectedSuggestion = null;

        var performSearchFromMouseClick = function(e, target) {
            if (e.which === constant.mouseButtons.left) {
                if (openDropDownBoxType() === "searchSuggest") {
                    webTrendsTracking.searchSuggestUsed = true;
                } else if (openDropDownBoxType() === "recentSearches") {
                    webTrendsTracking.recentSearchesUsed = true;
                }
                var clickedSearchQuery = $(target).find('span.result').text();
                if (clickedSearchQuery.substr(clickedSearchQuery.length - 3, 3) === '...') {
                    clickedSearchQuery = clickedSearchQuery.substr(0, clickedSearchQuery.length - 3);
                }
                currentSearchBox.find('input.search-box').val(clickedSearchQuery);
                currentSearchBox.find('a.go').click();
            }
        };

        $("div.search input.search-box").keyup(function(event) {
            if (!handleKeyboardNavigation(event.keyCode) && event.keyCode !== constant.keyCodes.enterButton) {
                jQuery.data(currentSearchBox[0], 'lastTypedSearchTerm', searchBoxDisplayedText());
            }

            if (searchBoxLastTypedText().length > 0 && searchBoxLastTypedText().length < constant.minimumInputCharactersBeforeSuggestions) {
                closeSuggestionsBox(currentSearchBox);
            }
        });

        if ($.fn.live) {
            $("div.search div.search-suggestions div.suggestions-results ul li").live('mouseenter', function() {
                setCurrentSelectedSuggestion($(this));
            });

            $("div.search div.search-suggestions div.suggestions-results").live('mouseleave', function() {
                setCurrentSelectedSuggestion(null);
            });

            $("div.search div.search-suggestions div.suggestions-results").live('mousedown', function(e) {
                if (e.which === constant.mouseButtons.right) {
                    closeSuggestionsBox(currentSearchBox);
                }
            });

            $("div.search div.search-suggestions div.suggestions-results ul li").live('mousedown', function(e) {
                performSearchFromMouseClick(e, $(this));
            });

        } else if ($.fn.livequery) {
            $("div.search div.search-suggestions div.suggestions-results ul li").livequery('mouseenter', function() {
                setCurrentSelectedSuggestion($(this));
            });

            $("div.search div.search-suggestions div.suggestions-results").livequery('mouseleave', function() {
                setCurrentSelectedSuggestion(null);
            });

            $("div.search div.search-suggestions div.suggestions-results").livequery('mousedown', function(e) {
                if (e.which === constant.mouseButtons.right) {
                    closeSuggestionsBox(currentSearchBox);
                }
            });

            $("div.search div.search-suggestions div.suggestions-results ul li").livequery('mousedown', function(e) {
                performSearchFromMouseClick(e, $(this));
            });
        }

        var handleKeyboardNavigation = function(keyCode) {
            if (keyCode === constant.keyCodes.upArrow || keyCode === constant.keyCodes.downArrow) {
                if (keyCode === constant.keyCodes.upArrow) {
                    if (currentSelectedSuggestion) {
                        setCurrentSelectedSuggestion(currentSelectedSuggestion.prev());
                    } else {
                        setCurrentSelectedSuggestion(currentSearchBox.find("div.search-suggestions div.suggestions-results ul li:last"));
                    }
                } else if (keyCode === constant.keyCodes.downArrow) {
                    if (currentSelectedSuggestion) {
                        setCurrentSelectedSuggestion(currentSelectedSuggestion.next());
                    } else {
                        setCurrentSelectedSuggestion(currentSearchBox.find("div.search-suggestions div.suggestions-results ul li:first"));
                    }
                }

                if (currentSelectedSuggestion) {
                    currentSearchBox.children('input.search-box').val(currentSelectedSuggestion.find('span span.result').text());
                } else {
                    currentSearchBox.children('input.search-box').val(searchBoxLastTypedText());
                }
                return true;
            } else {
                setCurrentSelectedSuggestion(null);
                return false;
            }
        };

        var setCurrentSelectedSuggestion = function(newSelectedSuggestion) {
            if (currentSelectedSuggestion) {
                currentSelectedSuggestion.removeClass("selected");
            }
            if (!newSelectedSuggestion || newSelectedSuggestion.length === 0) {
                currentSelectedSuggestion = null;
                return;
            }
            currentSelectedSuggestion = newSelectedSuggestion;
            currentSelectedSuggestion.addClass("selected");
        };
    };

    var initSearchSuggest = function() {
        $("div.search input.search-box").keyup(function(event) {
            if (searchBoxLastTypedText().length < constant.minimumInputCharactersBeforeSuggestions) {
                return;
            }

            if (event.keyCode === constant.keyCodes.upArrow || event.keyCode === constant.keyCodes.downArrow) { // don't request another search suggestion if it is a keyboard navigation action
                webTrendsTracking.searchSuggestUsed = true;
                return;
            }

            var rememberedUserSearchTerm = searchBoxLastTypedText();
            var rememberedSearchBox = currentSearchBox;
            $.ajax({
                url: constant.searchSuggestJSONPService,
                dataType: "jsonp",
                data: { search: searchBoxLastTypedText() },
                success: function(data) {
                    closeSuggestionsBox(rememberedSearchBox);

                    var results = data.suggestionGroups[0];
                    if (results === undefined || results.suggestions.length === 0 || results.indexName !== "searchterms" || // no suggestions found
                                rememberedUserSearchTerm !== searchBoxLastTypedText()) { // search results are outdated and no longer match the latest user's search term
                        return;
                    }

                    ensureTrimPathHasLoaded(function() {
                        var processedResults = postprocessSuggestionResults(results);
                        var trimPathResults = trimPathTemplateObject.process(processedResults, null);
                        currentSearchBox.children('div.search-suggestions').children('div.suggestions-results').html(trimPathResults);
                        openSuggestionsBox('searchSuggest');
                    });
                }
            });
        });

        var postprocessSuggestionResults = function(results) {
            results.webtrendsQuerystring = 'SearchSuggestUsed';
            for (var i = 0; i < results.suggestions.length; i++) {
                var numericNrResults = parseInt(results.suggestions[i].nrResults, 10);
                if (numericNrResults > constant.searchMaxResults) {
                    numericNrResults = constant.searchMaxResults;
                }
                results.suggestions[i].nrResults = numericNrResults;
            }
            return results;
        };
    };

    var initRecentSearches = function() {
        $("div.search input.search-box").click(function() {
            openRecentSearches();
        });

        $("div.search input.search-box").keyup(function(event) {
            if (searchBoxLastTypedText().length >= constant.minimumInputCharactersBeforeSuggestions) {
                return;
            }
            if (event.keyCode === constant.keyCodes.upArrow || event.keyCode === constant.keyCodes.downArrow) {
                webTrendsTracking.recentSearchesUsed = true;
                return;
            }
        });

        $("div.search span.clear-recent-searches").click(function() {
            var customer = asos.model.customer.load();
            customer.recentSearches = [];
            asos.model.customer.save(customer);
            closeSuggestionsBox(currentSearchBox);
            currentSearchBox.find('input.search-box').focus();
        });

        var openRecentSearches = function() {
            var customer = asos.model.customer.load();

            if (customer.recentSearches.length === 0 || searchBoxDisplayedText() !== '') {
                return;
            }

            ensureTrimPathHasLoaded(function() {
                var processedResults = postprocessRecentSearches(customer.recentSearches);
                var trimPathResults = trimPathTemplateObject.process(processedResults, null);
                currentSearchBox.children('div.search-suggestions').children('div.suggestions-results').html(trimPathResults);
                openSuggestionsBox('recentSearches');
                currentSearchBox.children('div.search-suggestions').children('div.recent-searches-header').show();
            });
        };

        var postprocessRecentSearches = function(recentSearches) {
            for (var i = 0; i < recentSearches.length; i++) {
                var searchTerm = recentSearches[i];
                recentSearches[i] = {
                    nrResults: '',
                    searchterm: searchTerm
                };
            }
            recentSearches.reverse();
            return { suggestions: recentSearches, webtrendsQuerystring: 'RecentSearchesUsed' };
        };

        var checkAndAddNewRecentSearch = function() {
            var newSearchTerm = constant.recentSearchesNewValue; // this has been encoded server side
            if (!newSearchTerm) {
                return;
            }

            var customer = asos.model.customer.load();

            for (var i = 0; i < customer.recentSearches.length; i++) {
                if (newSearchTerm.toLowerCase() === customer.recentSearches[i].toLowerCase()) {
                    customer.recentSearches.splice(i, 1);
                }
            }

            while (customer.recentSearches.length >= constant.recentSearchesToStore) {
                customer.recentSearches.shift();
            }
            customer.recentSearches.push(newSearchTerm);
            asos.model.customer.save(customer);
        };
        checkAndAddNewRecentSearch();
    };

    var ensureTrimPathHasLoaded = function(trimPathIsLoadedCallback) {
        if (!trimPathTemplateObject) {
            TemplateLoader.load(constant.trimPathTemplateFile, function(template) {
                trimPathTemplateObject = TrimPath.parseTemplate(template);
                trimPathIsLoadedCallback();
            }, function() { /* do nothing on error */ }, "");
        } else {
            trimPathIsLoadedCallback();
        }
    };

    var openSuggestionsBox = function(type) {
        closeSuggestionsBox(currentSearchBox);
        currentSearchBox.children('div.search-suggestions').show();
        jQuery.data(currentSearchBox[0], 'openDropDownBoxType', type);
    };

    var closeSuggestionsBox = function(searchBoxContext) {
        searchBoxContext.children('div.search-suggestions').hide();
        searchBoxContext.children('div.search-suggestions').children('div.recent-searches-header').hide();
    };

    init();
});
